package com.enation.app.javashop.core.distribution.service.impl;

import com.enation.app.javashop.core.base.model.enums.YesNoEnum;
import com.enation.app.javashop.core.distribution.model.dos.DistributionMissionDO;
import com.enation.app.javashop.core.distribution.model.dos.DistributionMissionDetailDO;
import com.enation.app.javashop.core.distribution.model.dto.CreateMissionDetailsDTO;
import com.enation.app.javashop.core.distribution.model.enums.DistributionMissionStatusEnums;
import com.enation.app.javashop.core.distribution.model.enums.RewardsTypeEnums;
import com.enation.app.javashop.core.distribution.model.vo.DistributionMissionDetailVO;
import com.enation.app.javashop.core.distribution.service.DistributionMissionDetailService;
import com.enation.app.javashop.core.distribution.service.DistributionMissionService;
import com.enation.app.javashop.core.promotion.coupon.model.dos.CouponDO;
import com.enation.app.javashop.core.promotion.coupon.model.dos.CouponTypeEnum;
import com.enation.app.javashop.core.promotion.coupon.service.CouponManager;
import com.enation.app.javashop.framework.context.UserContext;
import com.enation.app.javashop.framework.database.DaoSupport;
import com.enation.app.javashop.framework.exception.ServiceException;
import com.enation.app.javashop.framework.security.model.Seller;
import com.enation.app.javashop.framework.util.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author 王志杨
 * @since 2021/1/22 17:21
 * 团长任务service实现
 */
@Service
public class DistributionMissionDetailServiceImpl implements DistributionMissionDetailService {

    @Autowired
    @Qualifier("distributionDaoSupport")
    private DaoSupport daoSupport;

    @Autowired
    private DistributionMissionService distributionMissionService;

    @Autowired
    private CouponManager couponManager;

    @Override
    @Transactional(value = "distributionTransactionManager", rollbackFor = Exception.class)
    public void createMissionDetails(List<DistributionMissionDetailDO> distributionMissionDetailDOList) {

        // 1.参数校验
        Integer missionId = distributionMissionDetailDOList.get(0).getMissionId();
        DistributionMissionDO distributionMissionDO = distributionMissionService.getDistributionMissionByMissionId(missionId);
        this.validateDistributionMission(distributionMissionDO);

        // 2.奖励方式如果是代金券，要验证代金券是否可用
        Integer rewardsType = distributionMissionDO.getRewardsType();
        List<Integer> couponIdList = new ArrayList<>();
        if (RewardsTypeEnums.COUPON.getIndex() == rewardsType) {
            // 拼接代金券ID为字符串
            for (DistributionMissionDetailDO distributionMissionDetailDO : distributionMissionDetailDOList) {
                Integer level1CouponId = distributionMissionDetailDO.getLevel1CouponId();
                if (level1CouponId != null) {
                    couponIdList.add(level1CouponId);
                }
                Integer level2CouponId = distributionMissionDetailDO.getLevel2CouponId();
                if (level2CouponId != null) {
                    couponIdList.add(level2CouponId);
                }
                Integer level3CouponId = distributionMissionDetailDO.getLevel3CouponId();
                if (level3CouponId != null) {
                    couponIdList.add(level3CouponId);
                }
                Integer level4CouponId = distributionMissionDetailDO.getLevel4CouponId();
                if (level4CouponId != null) {
                    couponIdList.add(level4CouponId);
                }
            }
            // 去重
            couponIdList = couponIdList.stream().distinct().collect(Collectors.toList());
            String couponIds = couponIdList.stream().map(String::valueOf).collect(Collectors.joining(","));
            if (StringUtil.isEmpty(couponIds)) {
                throw new ServiceException("503", "请先选择代金券");
            }
            // 查询代金券是否可用
            List<CouponDO> marketingCouponList = couponManager.getMarketingCouponsByIds(couponIds, distributionMissionDO.getSellerId(), CouponTypeEnum.MARKETING_VOUCHER.value());
            if (marketingCouponList.size() != couponIdList.size()) {
                throw new ServiceException("503", "代金券不可用，请检查代金券");
            }
        }

        // 3.给子任务设置状态和团长任务名称后进行批量添加
        String missionName = distributionMissionDO.getMissionName();
        for (DistributionMissionDetailDO distributionMissionDetailDO : distributionMissionDetailDOList) {
            distributionMissionDetailDO.setMissionDetailStatus(DistributionMissionStatusEnums.NEW.getIndex());
            distributionMissionDetailDO.setMissionName(missionName);
            distributionMissionDetailDO.setIsDelete(0);
        }
        this.batchInsertMissionDetails(distributionMissionDetailDOList);
    }

    @Override
    @Transactional(value = "distributionTransactionManager", rollbackFor = Exception.class)
    public void updateMissionDetails(List<DistributionMissionDetailDO> distributionMissionDetailDOList) {
        // 先删除再插入
        Integer missionId = distributionMissionDetailDOList.get(0).getMissionId();
        deleteDistributionMissionDetailByMissionId(missionId);
        // 保存
        this.createMissionDetails(distributionMissionDetailDOList);
    }


    private void validateDistributionMission (DistributionMissionDO distributionMissionDO) {

        // 1.验证团长任务是否存在，任务明细是否已经创建
        if (ObjectUtils.isEmpty(distributionMissionDO)) {
            throw new ServiceException("500", "没有找到团长任务，请联系管理员");
        }

        // 2.验证团长任务状态，已下线的不能创建团长任务明细(子任务)
        if (DistributionMissionStatusEnums.OFFLINE.getIndex() == distributionMissionDO.getMissionStatus()) {
            throw new ServiceException("501", "该团长任务已下线，不能创建子任务");
        }

        // 3.待上线的团长任务可以修改子任务(先删除后添加),添加在主流程中
        else if (DistributionMissionStatusEnums.NEW.getIndex() == distributionMissionDO.getMissionStatus()) {
            this.deleteDistributionMissionDetailByMissionId(distributionMissionDO.getId());
        }

        // 4.待上线的团长任务不可以修改子任务，先查询有没有创建过子任务，没有创建的话可以保存
        else if (DistributionMissionStatusEnums.ONLINE.getIndex() == distributionMissionDO.getMissionStatus()) {
            // 验证任务明细是否已经创建
            List<DistributionMissionDetailDO> oldDistributionMissionDetailDOList = this.queryDistributionMissionDetailByMissionId(distributionMissionDO.getId());
            if (!CollectionUtils.isEmpty(oldDistributionMissionDetailDOList)) {
                throw new ServiceException("502", "该团长任务已上线，不能修改子任务");
            }
        }
        else {
            throw new ServiceException("500", "团长任务状态异常，请联系管理员");
        }
    }

    @Override
    public List<DistributionMissionDetailDO> queryDistributionMissionDetailByMissionId(Integer missionId) {
        String sql = "select * from es_distribution_mission_detail where mission_id=? and is_delete=0";
        return daoSupport.queryForList(sql, DistributionMissionDetailDO.class, missionId);
    }

    @Override
    public void deleteDistributionMissionDetailByMissionId(Integer missionId) {
        String sql = "update es_distribution_mission_detail set is_delete=1 where mission_id=? and is_delete=0";
        daoSupport.execute(sql, missionId);
    }

    @Override
    public void batchInsertMissionDetails(List<DistributionMissionDetailDO> distributionMissionDetailDOList) {
        daoSupport.batchInsert("es_distribution_mission_detail", distributionMissionDetailDOList);
    }

    // 查看任务详情
    @Override
    public CreateMissionDetailsDTO getMissionDetailByMisId(Integer missionId) {
        String sql = "select * from es_distribution_mission_detail where is_delete = 0 and mission_id=? ";
        List<DistributionMissionDetailVO> scheduleVOList = daoSupport.queryForList(sql, DistributionMissionDetailVO.class, missionId);

        CreateMissionDetailsDTO createMissionDetailsDTO = new CreateMissionDetailsDTO();
        for (DistributionMissionDetailVO disVO : scheduleVOList) {
            if (disVO.getMissionType().equals(0)) {
                createMissionDetailsDTO.setDayMissionDetail(disVO);
                continue;
            }
            if (disVO.getMissionType().equals(1)) {
                createMissionDetailsDTO.setMonthMissionDetail(disVO);
                continue;
            }
        }

        if(createMissionDetailsDTO.getDayMissionDetail()==null){
            createMissionDetailsDTO.setDayMissionDetail(new DistributionMissionDetailVO());
        }

        if(createMissionDetailsDTO.getMonthMissionDetail()==null){
            createMissionDetailsDTO.setMonthMissionDetail(new DistributionMissionDetailVO());
        }

        return createMissionDetailsDTO;
    }
}
